<template>
  <div class="p-4">
    <h2 class="text-2xl font-bold mb-4 text-gray-800 dark:text-gray-200">文本差异对比</h2>
    
    <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6">
      <!-- 原始文本 -->
      <div>
        <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
          原始文本
        </label>
        <textarea
          v-model="originalText"
          placeholder="输入原始文本..."
          class="w-full h-40 p-4 rounded-lg border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-transparent resize-none"
          @input="compareTexts"
        ></textarea>
      </div>

      <!-- 比较文本 -->
      <div>
        <label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
          比较文本
        </label>
        <textarea
          v-model="newText"
          placeholder="输入需要比较的文本..."
          class="w-full h-40 p-4 rounded-lg border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-transparent resize-none"
          @input="compareTexts"
        ></textarea>
      </div>
    </div>

    <!-- 对比选项 -->
    <div class="mb-6 flex gap-4">
      <label class="flex items-center">
        <input
          type="checkbox"
          v-model="ignoreCase"
          class="form-checkbox h-4 w-4 text-blue-500"
          @change="compareTexts"
        >
        <span class="ml-2 text-sm text-gray-700 dark:text-gray-300">忽略大小写</span>
      </label>
      <label class="flex items-center">
        <input
          type="checkbox"
          v-model="ignoreWhitespace"
          class="form-checkbox h-4 w-4 text-blue-500"
          @change="compareTexts"
        >
        <span class="ml-2 text-sm text-gray-700 dark:text-gray-300">忽略空白字符</span>
      </label>
    </div>

    <!-- 差异结果 -->
    <div v-if="showDiff" class="bg-white dark:bg-gray-800 p-4 rounded-lg border border-gray-200 dark:border-gray-700">
      <h3 class="text-lg font-semibold mb-4 text-gray-800 dark:text-gray-200">差异对比结果</h3>
      
      <!-- 统计信息 -->
      <div class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-4">
        <div class="text-center p-2 bg-gray-50 dark:bg-gray-900 rounded">
          <div class="text-sm text-gray-500 dark:text-gray-400">总行数</div>
          <div class="text-lg font-bold text-gray-900 dark:text-gray-100">{{ stats.totalLines }}</div>
        </div>
        <div class="text-center p-2 bg-gray-50 dark:bg-gray-900 rounded">
          <div class="text-sm text-gray-500 dark:text-gray-400">修改行数</div>
          <div class="text-lg font-bold text-yellow-500">{{ stats.modifiedLines }}</div>
        </div>
        <div class="text-center p-2 bg-gray-50 dark:bg-gray-900 rounded">
          <div class="text-sm text-gray-500 dark:text-gray-400">新增行数</div>
          <div class="text-lg font-bold text-green-500">{{ stats.addedLines }}</div>
        </div>
        <div class="text-center p-2 bg-gray-50 dark:bg-gray-900 rounded">
          <div class="text-sm text-gray-500 dark:text-gray-400">删除行数</div>
          <div class="text-lg font-bold text-red-500">{{ stats.deletedLines }}</div>
        </div>
      </div>

      <!-- 差异内容 -->
      <div class="space-y-1">
        <div
          v-for="(line, index) in diffResult"
          :key="index"
          :class="[
            'p-1 rounded font-mono text-sm whitespace-pre',
            {
              'bg-red-50 dark:bg-red-900/20 text-red-700 dark:text-red-300': line.type === 'deleted',
              'bg-green-50 dark:bg-green-900/20 text-green-700 dark:text-green-300': line.type === 'added',
              'bg-yellow-50 dark:bg-yellow-900/20 text-yellow-700 dark:text-yellow-300': line.type === 'modified',
              'text-gray-600 dark:text-gray-400': line.type === 'unchanged'
            }
          ]"
        >
          <span class="inline-block w-6 text-gray-400 select-none">{{ line.lineNumber }}</span>
          {{ line.content }}
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue'

const originalText = ref('')
const newText = ref('')
const ignoreCase = ref(false)
const ignoreWhitespace = ref(false)

interface DiffLine {
  content: string
  type: 'added' | 'deleted' | 'modified' | 'unchanged'
  lineNumber: number
}

interface DiffStats {
  totalLines: number
  modifiedLines: number
  addedLines: number
  deletedLines: number
}

const diffResult = ref<DiffLine[]>([])
const stats = ref<DiffStats>({
  totalLines: 0,
  modifiedLines: 0,
  addedLines: 0,
  deletedLines: 0
})

const showDiff = computed(() => originalText.value || newText.value)

const preprocessText = (text: string) => {
  let result = text
  if (ignoreCase.value) {
    result = result.toLowerCase()
  }
  if (ignoreWhitespace.value) {
    result = result.replace(/\s+/g, ' ').trim()
  }
  return result
}

const compareTexts = () => {
  const original = preprocessText(originalText.value)
  const modified = preprocessText(newText.value)

  const originalLines = original.split('\n')
  const modifiedLines = modified.split('\n')

  const result: DiffLine[] = []
  let lineNumber = 1
  
  // 使用最长公共子序列算法来找出差异
  const matrix = Array(originalLines.length + 1).fill(null)
    .map(() => Array(modifiedLines.length + 1).fill(0))

  // 填充矩阵
  for (let i = 1; i <= originalLines.length; i++) {
    for (let j = 1; j <= modifiedLines.length; j++) {
      if (originalLines[i - 1] === modifiedLines[j - 1]) {
        matrix[i][j] = matrix[i - 1][j - 1] + 1
      } else {
        matrix[i][j] = Math.max(matrix[i - 1][j], matrix[i][j - 1])
      }
    }
  }

  // 回溯找出差异
  let i = originalLines.length
  let j = modifiedLines.length
  const diff: DiffLine[] = []

  while (i > 0 || j > 0) {
    if (i > 0 && j > 0 && originalLines[i - 1] === modifiedLines[j - 1]) {
      diff.unshift({
        content: originalLines[i - 1],
        type: 'unchanged',
        lineNumber: i
      })
      i--
      j--
    } else if (j > 0 && (i === 0 || matrix[i][j - 1] >= matrix[i - 1][j])) {
      diff.unshift({
        content: modifiedLines[j - 1],
        type: 'added',
        lineNumber: j
      })
      j--
    } else if (i > 0 && (j === 0 || matrix[i][j - 1] < matrix[i - 1][j])) {
      diff.unshift({
        content: originalLines[i - 1],
        type: 'deleted',
        lineNumber: i
      })
      i--
    }
  }

  diffResult.value = diff

  // 更新统计信息
  stats.value = {
    totalLines: diff.length,
    modifiedLines: diff.filter(line => line.type === 'modified').length,
    addedLines: diff.filter(line => line.type === 'added').length,
    deletedLines: diff.filter(line => line.type === 'deleted').length
  }
}
</script> 